#ifndef BASE64_H_
#define BASE64_H_

namespace gpyp {
namespace base64 {

namespace {
static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
}

inline void encode(const char *data, size_t size, std::string &res) {
  const char *c = data, *end = data + size;
  res.clear();
  res.reserve((size_t)(size * 1.4) + 4);
  while(1) {
    char buf[] = {'=', '=', '=', '=', '\0'};
    bool b = false;
    buf[0] = table[(c[0] >> 2) & 0x3f];
    if (c + 1 < end) {
      buf[1] = table[((c[0] << 4) & 0x30) | ((c[1] >> 4) & 0xf)];
      if (c + 2 < end) {
        buf[2] = table[((c[1] << 2) & 0x3c) | ((c[2] >> 6) & 0x3)];
        buf[3] = table[c[2] & 0x3f];
        b = c + 3 == end;
      } else {
        buf[2] = table[(c[1] << 2) & 0x3c];
        b = true;
      }
    } else {
      buf[1] = table[(c[0] << 4) & 0x30];
      b = true;
    }
    res += buf;
    if (b) break;
    c += 3;
  }
}
inline void encode(const std::string &data, std::string &res) {
  encode(data.c_str(), data.size(), res);
}

}/*base64*/
}/*gpyp*/

#endif/*BASE64_H_*/
